package com.pyue.eam.regi.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pyue.eam.admin.api.base.BaseResult;
import com.pyue.eam.admin.api.dto.SimpleUserInfo;
import com.pyue.eam.admin.api.dto.chart.ChartData;
import com.pyue.eam.admin.api.dto.chart.ChartSeries;
import com.pyue.eam.admin.api.dto.chart.PerformanceUrl;
import com.pyue.eam.admin.api.entity.eam.EamRegion;
import com.pyue.eam.admin.api.entity.regi.*;
import com.pyue.eam.admin.api.enums.TaskStatusEnum;
import com.pyue.eam.admin.api.except.ApiAsserts;
import com.pyue.eam.admin.utils.AsyncUtil;
import com.pyue.eam.admin.utils.EamDateUtil;
import com.pyue.eam.admin.utils.EamUtils;
import com.pyue.eam.admin.utils.WxPushMessageUtil;
import com.pyue.eam.app.mapper.AppUserMapper;
import com.pyue.eam.app.service.AppUserService;
import com.pyue.eam.common.data.resolver.ParamResolver;
import com.pyue.eam.common.security.util.SecurityUtils;
import com.pyue.eam.regi.bo.MonthPerforEnum;
import com.pyue.eam.regi.mapper.*;
import com.pyue.eam.regi.module.message.entity.CqUserTaskMsgEntity;
import com.pyue.eam.regi.module.message.enums.MiniMsgEnum;
import com.pyue.eam.regi.module.message.service.CqUserTaskMsgService;
import com.pyue.eam.regi.module.region.utils.TaskPriceUtil;
import com.pyue.eam.regi.service.CqTaskLibService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 线边任务表
 *
 * @author lucc
 * @date 2023-10-12 20:39:55
 */
@Service
@AllArgsConstructor
public class CqTaskLibServiceImpl extends ServiceImpl<CqTaskLibMapper, CqTaskLibEntity> implements CqTaskLibService {
    private final PerformanceService performanceService;
    private final CqRegiLibMapper cqRegiLibMapper;
    private final CqTaskCheckMapper cqTaskCheckMapper;
    private final CqTaskAcceptMapper cqTaskAcceptMapper;
    private final CqCompanyMapper cqCompanyMapper;
    private final PartLibMapper partLibMapper;
    private final CqTaskPlanMapper cqTaskPlanMapper;
    private final TransactionTemplate transactionTemplate;
    private final AppUserService appUserService;
    private final AppUserMapper appUserMapper;
    private final ClientLibMapper clientLibMapper;
    private final CqTaskSortMapper cqTaskSortMapper;
    private final CqTaskDayMapper cqTaskDayMapper;
    private final CqUserTaskMsgService cqUserTaskMsgService;

    private static final String subPages = "/pages_sub/performance/";

    /**
     * 任务进度图-执行阶段-最新创建任务的top6
     */
    @Override
    public List<ChartSeries> arcbarData() {
        List<CqTaskLibEntity> cqTaskLibEntitieList = baseMapper.taskArcbarData();

        if (CollUtil.isNotEmpty(cqTaskLibEntitieList)) {
            return cqTaskLibEntitieList.stream().map(e -> {
                double resultData;
                if (Convert.toInt(e.getPlanPartNum(), 0) == 0 || Convert.toInt(e.getRealPartNum(), 0) == 0) {
                    resultData = 0.01D;
                } else if (Convert.toInt(e.getPlanPartNum(), 0) < Convert.toInt(e.getRealPartNum(), 0)) {
                    resultData = 0.95D;
                } else {
                    resultData = EamUtils.divCalcPercentage(e.getRealPartNum(), e.getPlanPartNum() * 100);
                }

                if (resultData == 0.0D) {
                    resultData = 0.01D;
                }

                return ChartSeries.builder().name(Convert.toStr(e.getTaskId())).data(resultData).build();
            }).collect(Collectors.toList());
        } else {
            return CollUtil.newArrayList(ChartSeries.builder().name("").data("0").build());
        }
    }

    @Override
    public ChartData columnData(Integer monthNum) {
        List<String> dateList = EamDateUtil.getDateList(LocalDate.now(), monthNum);

        List<? extends Number> sendTaskList = performanceService.getPerformanceByCode(MonthPerforEnum.send_task, dateList);
        List<? extends Number> overTaskList = performanceService.getPerformanceByCode(MonthPerforEnum.over_task, dateList);
        sendTaskList = CollUtil.sub(sendTaskList, CollUtil.size(sendTaskList) - monthNum, CollUtil.size(sendTaskList));
        overTaskList = CollUtil.sub(overTaskList, CollUtil.size(overTaskList) - monthNum, CollUtil.size(overTaskList));

        ArrayList<ChartSeries> seriesList = CollUtil.newArrayList(new ChartSeries("发布任务", sendTaskList), new ChartSeries("接受任务", overTaskList));

        return ChartData.builder().categories(dateList).series(seriesList).build();
    }

    @Override
    public List<CqTaskLibEntity> topTask() {
        Long roleTypeIdByUserId = appUserMapper.getRoleTypeIdByUserId(SecurityUtils.getUserId());
        ApiAsserts.isTrue(roleTypeIdByUserId != null, "用户角色为空");

        LambdaQueryWrapper<CqTaskLibEntity> wrapper = Wrappers.lambdaQuery(CqTaskLibEntity.class)
                .in(CqTaskLibEntity::getTaskStatus, "1", "2")
                .orderByDesc(CqTaskLibEntity::getCreateTime)
                .last(" limit 6");

        // System.out.println(SecurityUtils.);
        // appUserService.getWxOpenIdByAppUserId()

        List<CqTaskLibEntity> libEntityList = CollUtil.newArrayList();
        if (1L == roleTypeIdByUserId) {
            // 企业
            wrapper.eq(CqTaskLibEntity::getCreateBy, SecurityUtils.getUserId());
            libEntityList = list(wrapper);
        } else if (2L == roleTypeIdByUserId) {
            // 团长
            wrapper.eq(CqTaskLibEntity::getRegiChargeId, SecurityUtils.getUserId());
            libEntityList = list(wrapper);
        } else if (3L == roleTypeIdByUserId) {
            // 职工
            libEntityList = baseMapper.workerTaskList(SecurityUtils.getUserId());
        }

        List<Long> taskIdList = CollStreamUtil.toList(libEntityList, CqTaskLibEntity::getTaskId);

        // 解决sql空数值问题
        if (CollUtil.isNotEmpty(taskIdList)) {
            // 代办消息
            final List<CqTaskLibEntity> taskTodoCountList = cqUserTaskMsgService.getTaskTodoCount(taskIdList);
            Map<Long, Integer> todoMsgMap = CollStreamUtil.toMap(taskTodoCountList, CqTaskLibEntity::getTaskId, CqTaskLibEntity::getTodoCount);

            // 实际完成数
            final List<CqTaskSortEntity> sortEntityList = cqTaskSortMapper.getSortNumByTaskId(taskIdList);
            Map<Long, Integer> taskSortMap = CollStreamUtil.toMap(sortEntityList, CqTaskSortEntity::getTaskId, CqTaskSortEntity::getTotalNum);

            // 实际产生费用
            final List<CqTaskDayEntity> taskRealPriceList = cqTaskDayMapper.getTaskRealPriceByTaskIdList(taskIdList);
            Map<Long, Double> taskRealPriceMap = CollStreamUtil.toMap(taskRealPriceList, CqTaskDayEntity::getTaskId, CqTaskDayEntity::getCountWorkerPrice);

            libEntityList.forEach(e -> wrapTaskInfo(e, todoMsgMap, taskSortMap, taskRealPriceMap));
        }
        return libEntityList;
    }

    /**
     * 设置页四个绩效-不同身份不同的考核方式
     */
    @Override
    public List<PerformanceUrl> performance() {
        // todo 查找所有相关任务

        return CollUtil.newArrayList(PerformanceUrl.builder().id(RandomUtil.randomString(9)).name("任务数").value("7").url(subPages + "task_count/index").build(),
                PerformanceUrl.builder().id(RandomUtil.randomString(9)).name("上报数").value("0").url(subPages + "push_count/index").build(),
                PerformanceUrl.builder().id(RandomUtil.randomString(9)).name("消息数").value("6").url(subPages + "miss_count/index").build(),
                PerformanceUrl.builder().id(RandomUtil.randomString(9)).name("总费用").value("0").url(subPages + "costs_count/index").build());
    }

    @Override
    public List<SimpleUserInfo> workersBindTask(Long taskId, String workIds) {
        CqTaskLibEntity cqTaskLibEntity = getById(taskId);
        ApiAsserts.isTrue(cqTaskLibEntity != null, "任务不存在");

        List<Long> workerIdList = EamUtils.strSplitToLongList(workIds);
        ApiAsserts.isTrue(CollUtil.isNotEmpty(workerIdList), "请选择用户");

        String workerIdStr = workerIdList.stream().distinct().map(Convert::toStr).filter(StrUtil::isNotBlank).collect(Collectors.joining(StrUtil.COMMA));
        updateById(cqTaskLibEntity.setWorkUserIds(workerIdStr));

        List<Long> idList = EamUtils.strSplitToLongList(workerIdStr);
        return appUserService.getSimpleUserInfoByIds(CollUtil.distinct(idList));
    }

    @Override
    public Page<CqTaskLibEntity> datePage(Page page, CqTaskLibEntity cqTaskLib) {
        LambdaQueryWrapper<CqTaskLibEntity> wrapper = Wrappers.lambdaQuery(cqTaskLib).orderByDesc(CqTaskLibEntity::getCreateTime);

        Page<CqTaskLibEntity> dataPage = new Page<>();
        // 如果是团长
        Long roleTypeIdByUserId = appUserMapper.getRoleTypeIdByUserId(SecurityUtils.getUserId());
        ApiAsserts.isTrue(roleTypeIdByUserId != null, "用户角色为空",
                CollUtil.newArrayList(1L, 2L).contains(roleTypeIdByUserId), "您没有查看权限");

        if (1L == roleTypeIdByUserId) {
            dataPage = page(page, wrapper);
        } else if (2L == roleTypeIdByUserId) {
            // 团长
            if (Convert.toInt(cqTaskLib.getTaskStatus(), 0) > 0) {
                dataPage = page(page, wrapper.in(CqTaskLibEntity::getRegiChargeId, SecurityUtils.getUserId()));
            } else {
                dataPage = page(page, wrapper);
            }
        }

        if (CollUtil.isNotEmpty(dataPage.getRecords())) {
            List<Long> taskIdList = CollStreamUtil.toList(dataPage.getRecords(), CqTaskLibEntity::getTaskId);
            if (CollUtil.isEmpty(taskIdList)) {
                return dataPage;
            }

            // 代办消息
            final List<CqTaskLibEntity> taskTodoCountList = cqUserTaskMsgService.getTaskTodoCount(taskIdList);
            Map<Long, Integer> todoMsgMap = CollStreamUtil.toMap(taskTodoCountList, CqTaskLibEntity::getTaskId, CqTaskLibEntity::getTodoCount);

            // 实际完成数
            final List<CqTaskSortEntity> sortEntityList = cqTaskSortMapper.getSortNumByTaskId(taskIdList);
            Map<Long, Integer> taskSortMap = CollStreamUtil.toMap(sortEntityList, CqTaskSortEntity::getTaskId, CqTaskSortEntity::getTotalNum);

            // 实际产生费用
            final List<CqTaskDayEntity> taskRealPriceList = cqTaskDayMapper.getTaskRealPriceByTaskIdList(taskIdList);
            Map<Long, Double> taskRealPriceMap = CollStreamUtil.toMap(taskRealPriceList, CqTaskDayEntity::getTaskId, CqTaskDayEntity::getCountWorkerPrice);

            // 总费用计算和零件信息
            dataPage.getRecords().forEach(e -> wrapTaskInfo(e, todoMsgMap, taskSortMap, taskRealPriceMap));
        }
        return dataPage;
    }

    private void wrapTaskInfo(CqTaskLibEntity cqTaskLib, Map<Long, Integer> todoMsgMap, Map<Long, Integer> taskSortMap, Map<Long, Double> taskRealPriceMap) {
        // 零件
        if (StrUtil.isNotBlank(cqTaskLib.getPartId())) {
            PartLibEntity partLib = partLibMapper.selectById(cqTaskLib.getPartId());
            if (partLib != null) {
                cqTaskLib.setPartCode(partLib.getPartCode());
                cqTaskLib.setPartName(partLib.getPartName());
            }
        }
        // 代办消息数量
        if (todoMsgMap != null) {
            cqTaskLib.setTodoCount(todoMsgMap.get(cqTaskLib.getTaskId()));
        }

        // 实际完成数 realPartNum
        if (taskSortMap != null) {
            cqTaskLib.setRealPartNum(Convert.toInt(taskSortMap.get(cqTaskLib.getTaskId()), 0));
        }

        // 如果是计时任务 需要计算实际费用
        if ("1".equals(cqTaskLib.getTactics())) {
            cqTaskLib.setCountWorkerPrice(Convert.toDouble(taskRealPriceMap.get(cqTaskLib.getTaskId()), 0D));
        }

    }

    @Override
    public CqTaskLibEntity getDataById(Long taskId) {
        CqTaskLibEntity cqTaskLibEntity = getById(taskId);
        if (cqTaskLibEntity != null) {
            // 实际完成数
            final List<CqTaskSortEntity> sortEntityList = cqTaskSortMapper.getSortNumByTaskId(CollUtil.newArrayList(taskId));
            Map<Long, Integer> taskSortMap = CollStreamUtil.toMap(sortEntityList, CqTaskSortEntity::getTaskId, CqTaskSortEntity::getTotalNum);

            // 实际产生费用
            final List<CqTaskDayEntity> taskRealPriceList = cqTaskDayMapper.getTaskRealPriceByTaskIdList(CollUtil.newArrayList(taskId));
            Map<Long, Double> taskRealPriceMap = CollStreamUtil.toMap(taskRealPriceList, CqTaskDayEntity::getTaskId, CqTaskDayEntity::getCountWorkerPrice);

            // 总费用计算和零件信息
            wrapTaskInfo(cqTaskLibEntity, null, taskSortMap, taskRealPriceMap);

            // 已接单 1
            if (Convert.toInt(cqTaskLibEntity.getTaskStatus(), 0) >= TaskStatusEnum.EXECUTE.getCode()) {
                CqTaskAccept cqTaskAccept = baseMapper.getAcceptInfo(cqTaskLibEntity.getTaskId());
                ApiAsserts.isTrue(cqTaskAccept != null, "接单信息不存在");
                cqTaskLibEntity.setCqTaskAccept(cqTaskAccept);

                // 加入职工信息
                String workUserIds = cqTaskLibEntity.getWorkUserIds();
                if (StrUtil.isNotBlank(workUserIds)) {
                    List<Long> idList = EamUtils.strSplitToLongList(workUserIds);
                    cqTaskLibEntity.setWorkUserInfo(appUserService.getSimpleUserInfoByIds(CollUtil.distinct(idList)));
                }
            }

            // 已验收 8
            if (Convert.toInt(cqTaskLibEntity.getTaskStatus(), 0) >= TaskStatusEnum.CHECK_OVER.getCode()) {
                CqTaskCheck cqTaskCheck = baseMapper.getCheckInfo(cqTaskLibEntity.getTaskId());
                ApiAsserts.isTrue(cqTaskCheck != null, "验收信息不存在");
                cqTaskLibEntity.setCqTaskCheck(cqTaskCheck);
            }

            // 异步执行 如果是代办任务消息则取消
            AsyncUtil.executeAtHttp(() -> cqUserTaskMsgService.overTaskMsgStatus(cqTaskLibEntity.getTaskId(), SecurityUtils.getUserId()));
        }

        return cqTaskLibEntity;
    }

    @Override
    public Boolean acceptCqTask(Long taskId) {
        ApiAsserts.isTrue(taskId != null, "任务不存在");
        CqTaskLibEntity cqTaskLib = getById(taskId);
        ApiAsserts.isTrue(cqTaskLib != null, "任务不存在");

        // 获取当前登录人对应的团
        final Long userId = SecurityUtils.getUserId();
        CqRegiLibEntity regiLibEntity = cqRegiLibMapper.getRegiByUserId(userId);
        ApiAsserts.isTrue(regiLibEntity != null, "请先维护好团信息再承接任务");

        // 修改任务状态
        assert regiLibEntity != null;
        assert cqTaskLib != null;
        updateById(cqTaskLib.setTaskStatus(TaskStatusEnum.EXECUTE.getStrCode()).setRegiId(regiLibEntity.getRegiId()).setRegiChargeId(userId));

        // 加入任务表
        CqTaskAccept cqTaskAccept = new CqTaskAccept().setTaskId(taskId).setRegiId(regiLibEntity.getRegiId()).setChargeAvatar(regiLibEntity.getRegiAvatar());
        cqTaskAcceptMapper.insert(cqTaskAccept);

        return Boolean.TRUE;
    }

    @Override
    public Boolean appleCheckCqTask(CqTaskCheck cqTaskCheck) {
        ApiAsserts.isTrue(cqTaskCheck.getTaskId() != null, "任务不存在");
        CqTaskLibEntity cqTaskLib = getById(cqTaskCheck.getTaskId());
        ApiAsserts.isTrue(cqTaskLib != null, "任务不存在");

        // 如果是计时方式 - 费用以实际报工的为准
        assert cqTaskLib != null;
        if ("1".equals(cqTaskLib.getTactics())) {
            // 重新计算任务总费用
            cqTaskLib.setCountPrice(cqTaskDayMapper.getTaskRealPriceByTaskId(cqTaskCheck.getTaskId()));
        }

        boolean updateFlag = updateById(cqTaskLib.setTaskStatus(TaskStatusEnum.CHECK_WAIT.getStrCode()));
        // 团长申请验收通知
        sandAppleCheckNotice(cqTaskLib, updateFlag);
        sandAppleCheckTodoTask(cqTaskLib.getTaskId(), cqTaskLib.getCreateBy());

        return Boolean.TRUE;
    }

    private void sandAppleCheckTodoTask(Long cqTaskId, String taskLibCreateBy) {
        saveTodoTaskMsg(cqTaskId, TaskStatusEnum.CHECK_WAIT.getStrCode(), CollUtil.newArrayList(Convert.toLong(taskLibCreateBy)));
    }

    // 团长申请验收通知
    private void sandAppleCheckNotice(CqTaskLibEntity cqTaskLib, boolean updateFlag) {
        String wxOpenId = appUserService.getWxOpenIdByAppUserId(Convert.toStr(cqTaskLib.getCreateBy(), ""));

        if (updateFlag && StrUtil.isNotBlank(wxOpenId) && ParamResolver.getBool("MP_NOTICE")) {
            HashMap<String, String> dataMap = MapUtil.newHashMap();
            dataMap.put("thing2", partLibMapper.getNameById(cqTaskLib.getPartId()) + "-验收");  // 项目名称
            dataMap.put("thing3", cqTaskLib.getAddress() + cqTaskLib.getAddressDetail());    // 项目地址
            dataMap.put("thing1", "验收通过"); // 验收事项
            // 推送消息
            WxPushMessageUtil.templateMessage(wxOpenId, "xbQypz2zjYMFBA9Fr4lldDpS0VVWGMfD68tnQWO_1J0", dataMap);
        }
    }

    @Override
    public Boolean updateDataById(CqTaskLibEntity cqTaskLib) {
        cqTaskLib.setCountPrice(privateCultCountPrice(cqTaskLib));
        return updateById(cqTaskLib);
    }

    @Override
    public Boolean acceptTaskPlan(Long taskId, Long taskPlanId) {
        CqTaskPlanEntity taskPlanEntity = cqTaskPlanMapper.selectById(taskPlanId);
        CqTaskLibEntity taskLib = getById(taskId);
        ApiAsserts.isTrue(taskLib != null, "任务不存在", taskPlanEntity != null, "任务方案不存在");

        assert taskLib != null;
        assert taskPlanEntity != null;
        taskLib.setTaskPlanId(taskPlanEntity.getId());
        taskLib.setPerNum(taskPlanEntity.getPerNum());
        taskLib.setPlanStart(taskPlanEntity.getPlanStart());
        taskLib.setPlanEnd(taskPlanEntity.getPlanEnd());
        taskLib.setPlanPartNum(taskPlanEntity.getPlanPartNum());
        // 计时情况保存工时费
        if ("1".equals(taskPlanEntity.getTactics())) {
            ApiAsserts.isTrue(taskPlanEntity.getWorkHour() != null, "任务方案缺少工时费");
            taskLib.setWorkHour(taskPlanEntity.getWorkHour());
        }
        taskLib.setHourPrice(taskPlanEntity.getHourPrice());
        taskLib.setTactics(taskPlanEntity.getTactics());
        taskLib.setCountPrice(taskPlanEntity.getCountPrice());

        // 团负责人
        taskLib.setRegiChargeId(Convert.toLong(taskPlanEntity.getCreateBy(), 0L));
        // 团id
        taskLib.setRegiId(taskPlanEntity.getRegiId());
        // 配置任务状态为执行中
        taskLib.setTaskStatus(TaskStatusEnum.EXECUTE.getCode().toString());

        // 加入接受团信息
        Long regiId = taskPlanEntity.getRegiId();
        ApiAsserts.isTrue(regiId != null, "团信息不存在");

        // 加入任务表
        CqTaskAccept cqTaskAccept =
                new CqTaskAccept().setTaskId(taskId).setRegiId(taskPlanEntity.getRegiId()).setChargeAvatar(taskPlanEntity.getChargeAvatar());

        AtomicBoolean updateFlag = new AtomicBoolean(false);
        transactionTemplate.execute(status -> {
            cqTaskAcceptMapper.insert(cqTaskAccept);
            updateFlag.set(updateById(taskLib));
            return Boolean.TRUE;
        });

        acceptTaskPlanNotice(updateFlag, taskPlanEntity.getCreateBy(), taskLib);
        acceptTaskPlanTodoMsg(taskLib.getTaskId(), taskPlanEntity.getCreateBy());

        return Boolean.TRUE;
    }

    // 接受方案后加入代办
    private void acceptTaskPlanTodoMsg(Long taskId, String planCreateBy) {
        saveTodoTaskMsg(taskId, TaskStatusEnum.EXECUTE.getStrCode(), CollUtil.newArrayList(Convert.toLong(planCreateBy)));
    }

    @Override
    public Map<String, Integer> getTaskNum() {
        // 代办任务数量
        List<CqUserTaskMsgEntity> taskMsgEntityList = cqUserTaskMsgService.getTaskMes(SecurityUtils.getUserId(), MiniMsgEnum.TODO_TASK.getType());
        // 从记录中找到最后一条记录 再通过updateTime找到最后记录的时间
        if (CollUtil.isEmpty(taskMsgEntityList)) {
            return new HashMap<>();
        }

        Map<String, List<Long>> toViedData = CollStreamUtil.groupKeyValue(taskMsgEntityList, CqUserTaskMsgEntity::getBizStatus, CqUserTaskMsgEntity::getBizId);

        HashMap<String, Integer> map = new HashMap<>();
        map.put("a", getSize(toViedData, "0"));
        map.put("b", getSize(toViedData, "1"));
        map.put("c", getSize(toViedData, "3"));
        map.put("d", getSize(toViedData, "8"));
        return map;
    }

    private static int getSize(Map<String, List<Long>> toViedData, String number) {
        List<Long> longList = toViedData.get(number);
        if (CollUtil.isEmpty(longList)) {
            return 0;
        }
        return CollUtil.size(CollUtil.distinct(longList));
    }


    // 方案认可微信通知
    private void acceptTaskPlanNotice(AtomicBoolean updateFlag, String planCreateBy, CqTaskLibEntity cqTaskLib) {
        List<String> wxOpenIdByAppUserId = appUserService.getWxOpenIdByAppUserId(CollUtil.newArrayList(Convert.toLong(planCreateBy, 0L)));
        if (updateFlag.get() && CollUtil.isNotEmpty(wxOpenIdByAppUserId) && ParamResolver.getBool("MP_NOTICE")) {
            // 发送微信公众号通知-给团长
            HashMap<String, String> dataMap = MapUtil.newHashMap();
            dataMap.put("thing10", partLibMapper.getNameById(cqTaskLib.getPartId()) + "-方案认可");  // 单据名称
            dataMap.put("thing7", Convert.toStr(clientLibMapper.getNameById(cqTaskLib.getClientId()), "无"));    // 客户名称
            dataMap.put("time11", LocalDate.now().toString()); // 通过时间
            // 推送消息
            WxPushMessageUtil.templateMessage(wxOpenIdByAppUserId, "xVgI6qrddeinqam0rkpFWnGmvDTA2qYrfn3ZLiP8rbE", dataMap);
        }
    }

    /**
     * 企业验收任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean checkCqTask(CqTaskCheck cqTaskCheck) {
        ApiAsserts.isTrue(cqTaskCheck.getTaskId() != null, "任务不存在", cqTaskCheck.getCheckFlag() != null, "传参错误");
        CqTaskLibEntity cqTaskLib = getById(cqTaskCheck.getTaskId());
        ApiAsserts.isTrue(cqTaskLib != null, "任务不存在");

        // 找到这个任务对应的团id 这个人对应的公司id
        BaseResult baseResult = baseMapper.getRegiIdAndCompanyId(cqTaskCheck.getTaskId());
        cqTaskCheck.setRegiId(Convert.toLong(baseResult.getV1(), 0L));
        cqTaskCheck.setCompanyId(Convert.toLong(baseResult.getV2(), 0L));
        cqTaskCheckMapper.insert(cqTaskCheck);

        assert cqTaskLib != null;
        // checkFlag  1是同意 2是驳回 // todo 发送微信公众号消息
        if ("1".equals(cqTaskCheck.getCheckFlag())) {
            boolean updateFlag = updateById(cqTaskLib.setTaskStatus(TaskStatusEnum.CHECK_OVER.getStrCode()));
            // todo 发送团长验收通过通知
            sendCheckCqTaskNotice(updateFlag, cqTaskLib);
            sendCheckCqTodoTask(cqTaskLib.getRegiChargeId(), cqTaskLib.getTaskId());
        } else {
            updateById(cqTaskLib.setTaskStatus(TaskStatusEnum.EXECUTE.getStrCode()));
        }

        return Boolean.TRUE;
    }

    private void sendCheckCqTodoTask(Long regiChargeId, Long taskId) {
        saveTodoTaskMsg(taskId, TaskStatusEnum.CHECK_WAIT.getStrCode(), CollUtil.newArrayList(Convert.toLong(regiChargeId)));
    }

    // 企业验收任务通知
    private void sendCheckCqTaskNotice(boolean updateFlag, CqTaskLibEntity cqTaskLib) {
        String wxOpenId = appUserService.getWxOpenIdByAppUserId(Convert.toStr(cqTaskLib.getRegiChargeId(), ""));

        if (updateFlag && StrUtil.isNotBlank(wxOpenId) && ParamResolver.getBool("MP_NOTICE")) {
            HashMap<String, String> dataMap = MapUtil.newHashMap();
            dataMap.put("thing2", partLibMapper.getNameById(cqTaskLib.getPartId()) + "-成功验收");  // 单据名称
            dataMap.put("thing3", clientLibMapper.getNameById(cqTaskLib.getClientId()));    // 客户名称
            dataMap.put("time11", LocalDate.now().toString());    // 通过时间
            // 推送消息
            WxPushMessageUtil.templateMessage(wxOpenId, "o8UMXA0ECRiZz8oajHdLnyY2T9FHPMIl6CG_05fCtgA", dataMap);
        }
    }

    @Override
    public Long saveTask(CqTaskLibEntity cqTaskLib) {
        // 找到登录人对于的公司id
        Long companyId = cqCompanyMapper.getCompanyIdByUserId();
        // todo 自动创建企业信息
        ApiAsserts.isTrue(companyId != null, "请先维护好公司信息再发布任务");

        // todo 设置预计价格
        cqTaskLib.setForecastPrice(TaskPriceUtil.priceRange(cqTaskLib));
        // 单位价格区间
        EamRegion eamRegion = TaskPriceUtil.getEamRegion(cqTaskLib.getAddress());
        if (eamRegion != null) {
            String priceRange = StrUtil.concat(Boolean.TRUE, eamRegion.getHourMax().toString(), "～", eamRegion.getHourMax().toString());
            cqTaskLib.setRegionPriceRange(priceRange);
        }

        save(cqTaskLib.setCompanyId(companyId));

        // 微信公众号通知
        saveTaskNotice(cqTaskLib);
        // 找到所有团长 - 加入代办消息
        List<Long> regiUserid = appUserService.getAllRegiUserId();
        saveTodoTaskMsg(cqTaskLib.getTaskId(), TaskStatusEnum.PUBLISH.getStrCode(), regiUserid);

        return cqTaskLib.getTaskId();
    }

    // 新增任务加入代办消息列表
    private void saveTodoTaskMsg(Long taskId, String taskStatus, List<Long> regiUserid) {
        if (CollUtil.isEmpty(regiUserid)) {
            return;
        }
        List<CqUserTaskMsgEntity> msgEntityList = regiUserid.stream().map(e -> CqUserTaskMsgEntity.builder()
                        .userId(e).bizId(taskId).bizStatus(taskStatus)
                        .msgType(MiniMsgEnum.TODO_TASK.getType())
                        .viewFlag("0")
                        .build())
                .collect(Collectors.toList());

        // 加入代办消息
        cqUserTaskMsgService.saveBatch(msgEntityList);
    }

    /**
     * 发布任务后-公众号通知所有团长上报方案
     */
    private void saveTaskNotice(CqTaskLibEntity cqTaskLib) {
        List<String> toUserList = appUserService.getAllRegiWxOpenId();

        // todo 派工单通知
        if (CollUtil.isNotEmpty(toUserList) && ParamResolver.getBool("MP_NOTICE_REGI")) {
            HashMap<String, String> dataMap = MapUtil.newHashMap();
            dataMap.put("thing17", clientLibMapper.getNameById(cqTaskLib.getClientId()));  // 客户名称
            dataMap.put("thing15", partLibMapper.getNameById(cqTaskLib.getPartId()) + "-挑选");    // 工单名称
            dataMap.put("character_string31", Convert.toInt(cqTaskLib.getPlanPartNum(), 0).toString()); // 工单数量
            dataMap.put("time8", cqTaskLib.getPlanStart() != null ? cqTaskLib.getPlanStart().toString() : LocalDate.now().toString()); // 截止时间
            dataMap.put("thing9", "请尽快上报任务方案,以便优先被客户选中"); // 通知事项
            // 推送消息
            WxPushMessageUtil.templateMessage(toUserList, "xVgI6qrddeinqam0rkpFWnGmvDTA2qYrfn3ZLiP8rbE", dataMap);
        }
    }

    // 根据任务类型计算费用
    private static Double privateCultCountPrice(CqTaskLibEntity cqTaskLib) {
        // 计算价格
        Double uniPrice = Convert.toDouble(cqTaskLib.getHourPrice(), 0D);
        if (uniPrice == 0D) {
            cqTaskLib.setCountPrice(0D);
        }

        // 多个人
        Double perNun = Convert.toDouble(cqTaskLib.getPerNum(), 0D);
        if (Objects.equals(Convert.toStr(cqTaskLib.getTactics()), "1")) {
            // 计时 todo 参数配置
            uniPrice = uniPrice >= 4 ? uniPrice : 4;
            return uniPrice * perNun * 55;
        } else if (Objects.equals(Convert.toStr(cqTaskLib.getTactics()), "2")) {
            // 计件
            return uniPrice * Convert.toInt(cqTaskLib.getPlanPartNum(), 0);
        } else if (Objects.equals(Convert.toStr(cqTaskLib.getTactics()), "3")) {
            // 记天
            return perNun * 400;
        } else {
            return 0D;
        }
    }


}

